
#ifndef __APP_UPDATE_H_
#define __APP_UPDATE_H_

#include <stdint.h>
#include "dataproc.h"
#include "rtctime.h"
#include "mytype.h"

#ifdef _APP_UPDATE_MODULE_
#define MY_EXT
#else
#define MY_EXT extern
#endif

#define FIL_OPEN_R 1  //只读，没有则打开失败
#define FIL_OPEN_W 2  //只写，没有则新建
#define FIL_OPEN_WA 4 //只写，始终新建

/********************************************************************************
*  hash iap file head
********************************************************************************/
typedef struct
{
	uint32_t app_site;
	uint32_t app_len;
	uint8_t aes_mode;
	uint16_t aes_bit;
} iap_hash_head_type;

/********************************************************************************
*  iap error st
********************************************************************************/
typedef union
{
	uint16_t st;
	struct
	{
		uint16_t err_crc : 1;
		uint16_t err_no_file : 1;
		uint16_t err_file_read : 1;
		uint16_t err_sum : 1;
		uint16_t err_size : 1;
		uint16_t id_err : 1;
		uint16_t verify : 1;
		uint16_t aes_mode : 1;
		uint16_t md5 : 1;
		uint16_t sha : 1;
	} bits;
} iap_err_type;

/********************************************************************************
*  iap info out
********************************************************************************/
typedef union
{
	uint8_t st;
	struct
	{
		uint8_t check_ok : 1;
		uint8_t app_diff : 1;	//文件内容和FLASH原数据有差异
		uint8_t update_req : 1;
		uint8_t update_ok : 1;
		uint8_t update_err : 1;
	} bits;
} iap_out_type;

/********************************************************************************
*  iap control
********************************************************************************/
struct updata_ctr_str
{
	// config
	uint32_t app_mem_base;
	uint32_t app_mem_size;
	uint32_t id_mem_offset;
	uint32_t id_mem_value;

	// status
	iap_err_type err;
	iap_out_type out;
	iap_hash_head_type hash_iap_head;

	uint32_t enc_file_size;
	uint32_t app_bin_size;
	uint8_t *buff;
	uint8_t *comm_buff;
	uint8_t *head_buff;
	const char *src_file;
	const char *out_file;
};

MY_EXT struct updata_ctr_str iap_obj;

/*  */
void swap_iap_update(uint8_t check0_or_program1);
void enc_iap_update(uint8_t check0_or_program1);

void ap_ext_start(void);
void ap_ext_end(void);

/* hal opt */
uint8_t ap_flash_read(uint32_t addr, uint32_t len, uint8_t *pdat);
uint8_t ap_flash_write(uint32_t addr, uint32_t len, uint8_t *pdat);
uint8_t ap_flash_erase(uint32_t addr_start, uint32_t addr_end);

/* file opt */
uint16_t ap_file_open(const char *file_name, uint8_t mode);
uint16_t ap_file_read(void *buff, uint16_t len);
uint16_t ap_file_write(void *buff, uint16_t len);
uint32_t ap_file_seek(uint32_t site);
uint32_t ap_file_size_get(void);
uint16_t ap_file_close(void);

#undef MY_EXT

#endif /* __APP_UPDATE_H_ */
